package com.example.gybicycle.common.util;

import  com.alibaba.fastjson.JSON;
import  com.alibaba.fastjson.JSONArray;
import  com.alibaba.fastjson.JSONObject;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import lombok.SneakyThrows;
import org.springframework.util.StringUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;

/**
 * 二维码生成工具类
 * Created by chenzan on 2022/09/19
 */
public class QRCodeUtil {
    private static final int QRCODE_SIZE = 320; // 二维码尺寸，宽度和高度均是320
    private static final String FORMAT_TYPE = "PNG"; // 二维码图片类型

    /**
     * 默认需要logo,无底部文字
     * 返回 BufferedImage 可以使用ImageIO.write(BufferedImage, "png", outputStream);输出
     *
     * @param dataStr
     * @return 返回 BufferedImage 可以使用ImageIO.write(BufferedImage, "png", outputStream);输出
     */
    @SneakyThrows
    public static BufferedImage getQRCodeImage(String dataStr) {
        BufferedImage bufferedImage = getQRCodeImage(dataStr, "xxx", null);
        return bufferedImage;
    }

    /**
     * 默认需要logo,无底部文字
     *
     * @param dataStr
     * @return 返回字节数组
     */
    @SneakyThrows
    public static byte[] getQRCodeByte(String dataStr) {
        BufferedImage bufferedImage = getQRCodeImage(dataStr, "xx", null);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, FORMAT_TYPE, outputStream);
        byte[] byteData = outputStream.toByteArray();
        return byteData;
    }

    /**
     * 默认需要logo，包含底部文字 文字为空则不显示文字
     * 返回 BufferedImage 可以使用ImageIO.write(BufferedImage, "png", outputStream);输出
     *
     * @param dataStr
     * @return
     */
    @SneakyThrows
    public static BufferedImage getQRCodeImage(String dataStr, String bottomText) {
        BufferedImage bufferedImage = getQRCodeImage(dataStr, "xx", bottomText);
        return bufferedImage;
    }

    /**
     * 默认需要logo，包含底部文字 文字为空则不显示文字
     *
     * @param dataStr
     * @return 返回字节数组
     */
    @SneakyThrows
    public static byte[] getQRCodeByte(String dataStr, String bottomText) {
        BufferedImage bufferedImage = getQRCodeImage(dataStr, "xx", bottomText);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, FORMAT_TYPE, outputStream);
        byte[] byteData = outputStream.toByteArray();
        return byteData;
    }

    /**
     * 获取二维码图片
     *
     * @param dataStr    二维码内容
     * @param needLogo   是否需要添加logo
     * @param bottomText 底部文字       为空则不显示
     * @return
     */
    @SneakyThrows
    public static BufferedImage getQRCodeImage(String dataStr, String  logPath, String bottomText) {
        if (dataStr == null) {
            throw new RuntimeException("未包含任何信息");
        }
        HashMap<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");    //定义内容字符集的编码
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);        //定义纠错等级
        hints.put(EncodeHintType.MARGIN, 1);
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
//        BitMatrix bitMatrix = qrCodeWriter.encode(new String(dataStr.getBytes("utf-8"),"ISO-8859-1"), BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
        BitMatrix bitMatrix = qrCodeWriter.encode(dataStr, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
        int width = bitMatrix.getWidth();
        int height = bitMatrix.getHeight();
        int tempHeight = height;
        if (StringUtils.hasText(bottomText)) {
            tempHeight = tempHeight + 12;
        }
        BufferedImage image = new BufferedImage(width, tempHeight, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
            }
        }
        // 判断是否添加logo
        if (logPath!=null) {
            insertLogoImage(image,logPath);
        }
        // 判断是否添加底部文字
        if (StringUtils.hasText(bottomText)) {
            addFontImage(image, bottomText);
        }
        return image;
    }

    /**
     * 插入logo图片
     *
     * @param source 二维码图片
     * @throws Exception
     */
    private static void insertLogoImage(BufferedImage source,String logPath) throws Exception {
        // 默认logo放于resource/static/image目录下
//        ClassPathResource classPathResource = new ClassPathResource("static/image/logo.png");
//        InputStream inputStream = classPathResource.getInputStream();
        InputStream inputStream =new FileInputStream(logPath);
        if (inputStream == null || inputStream.available() == 0) {
            return;
        }
        Image src = ImageIO.read(inputStream);
        int width = 50;
        int height = 50;

        Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
        BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics g = tag.getGraphics();
        g.drawImage(image, 0, 0, null); // 绘制缩小后的图
        g.dispose();
        src = image;

        // 插入LOGO
        Graphics2D graph = source.createGraphics();
        int x = (QRCODE_SIZE - width) / 2;
        int y = (QRCODE_SIZE - height) / 2;
        graph.drawImage(src, x, y, width, height, null);
        Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
        graph.setStroke(new BasicStroke(3f));
        graph.draw(shape);
        graph.dispose();
    }

    private static void addFontImage(BufferedImage source, String declareText) {
        //生成image
        int defineWidth = QRCODE_SIZE;
        int defineHeight = 20;
        BufferedImage textImage = new BufferedImage(defineWidth, defineHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = (Graphics2D) textImage.getGraphics();
        //开启文字抗锯齿
        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,   RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g2.setBackground(Color.WHITE);
        g2.clearRect(0, 0, defineWidth, defineHeight);
        g2.setPaint(Color.BLACK);
        FontRenderContext context = g2.getFontRenderContext();
        //部署linux需要注意 linux无此字体会显示方块

        Font font = new Font("宋体", Font.BOLD, 15);
//        Font font =new Font("WenQuanYi Zen Hei", Font.PLAIN, 15);
        g2.setFont(font);
        LineMetrics lineMetrics = font.getLineMetrics(declareText, context);
        FontMetrics fontMetrics= g2.getFontMetrics();
//        FontMetrics fontMetrics = FontDesignMetrics.getMetrics(font);
        float offset = (defineWidth - fontMetrics.stringWidth(declareText)) / 2;
        float y = (defineHeight + lineMetrics.getAscent() - lineMetrics.getDescent() - lineMetrics.getLeading()) / 2;
        g2.drawString(declareText, (int) offset, (int) y);

        Graphics2D graph = source.createGraphics();
        //开启文字抗锯齿
        graph.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,   RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        //添加image
        int width = textImage.getWidth(null);
        int height = textImage.getHeight(null);

        Image src = textImage;
        graph.drawImage(src, 0, QRCODE_SIZE - 8, width, height, Color.WHITE, null);
        graph.dispose();
    }
    public static String createImg(String txt,String name,String filePath){
        try{
            BufferedImage bufferedImage = QRCodeUtil.getQRCodeImage(txt,null,
                    name);
            File file=new File(filePath);
            if(!file.exists())
                file.mkdirs();
            ImageIO.write(bufferedImage,"png",file);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
       return filePath;
    }
    public static String createImg(String txt,String name,String filePath,String yx){
        try{
            BufferedImage bufferedImage = QRCodeUtil.getQRCodeImage(txt,yx,
                    name);
            File file=new File(filePath);
            ImageIO.write(bufferedImage,"png",file);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
        return filePath;
    }
/*    public static String  creatWxQRCodeImg(){
        // 初始化WxMpService
        WxMpService wxMpService = new WxMpServiceImpl();
        // 设置配置
        wxMpService.setWxMpConfigStorage(new WxMpInMemoryConfigStorage("appId", "appSecret", "token", "aesKey", "msgDataFormat"));

        // 创建二维码
        final String path = "pages/index/index";
        final String scene = "123456"; // 这里的scene值可以为数字，也可以为字符串
        final String page = "pages/index/index?user=123&action=456"; // 带参数的页面路径

        WxMpQrCodeTicket ticket = wxMpService.getQrcodeService().createQrCode(path, scene, page);

        // 获取二维码图片
        File file = wxMpService.getQrcodeService().getQrCode(ticket.getTicket());
        // 保存图片到本地或者处理图片
        // file.transferTo(new File("qrcode.jpg"));
        return "";
    }*/
    public static void main(String[] args) throws IOException {
        String txt=" [ { \"title\":\"扫码开锁\"," +
                "\"click\":\"CLICK IT>\"," +
                "\"icon\":\"scancode.png\"," +
                "\"path\":\"\"," +
                "\"class\":\"open\"," +
                "\"state\":\"1\"," +
                "}," +
                "{" +
                "\"title\":\"扫码关锁\"," +
                "\"click\":\"CLICK IT>\"," +
                "\"icon\":\"scancode.png\"," +
                "\"path\":\"\"," +
                "\"class\":\"close\"," +
                "\"state\":\"2\"," +
                "}," +
                "{" +
                "\"title\":\"故障处理\"," +
                "\"click\":\"CLICK IT>\"," +
                "\"icon\":\"failure_white.png\"," +
                "\"path\":\"/pages/troubleShooting\"," +
                "\"class\":\"troubleShooting\"," +
                "}]";
        Object object= JSON.parse(txt);
        System.out.println(object);
//        String
//        String test="https://xfcs.everbf.com/minis?routerId=49";
//        String test2="https://xfcs.everbf.com/mini?routerId=332";
////        createImg(test,"潮玩空间","D:\\create\\resources\\49.png");
////        createImg(test2,"飞影动漫城","D:\\create\\resources\\332.png");
//        createImg("https://xfcs.everbf.com/test?routerId="+336+"&routerName=奇乐熊","奇乐熊","D:\\create\\resources\\336.png","D:\\image\\fire\\media\\logo.png");
//        createImg("https://xfcs.everbf.com/test?routerId="+337+"&routerName=伊人名妆","伊人名妆","D:\\create\\resources\\337.png","D:\\image\\fire\\media\\logo.png");
//        createImg("https://xfcs.everbf.com/test?routerId="+49+"&routerName=潮玩空间","潮玩空间","D:\\create\\resources\\49.png","D:\\image\\fire\\media\\logo.png");
//        createImg("https://xfcs.everbf.com/test?routerId="+332+"&routerName=飞影动漫城","飞影动漫城","D:\\create\\resources\\332.png","D:\\image\\fire\\media\\logo.png");
//        String testx="https://xfcs.everbf.com/mini";
//        createImg(test,"testx","D:\\create\\resources\\testx.png");
    }

}